﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public abstract class MetadataOrder : SyntaxNode, IMetadataOrder
{
    private SyntaxToken? _fixKeywordToken;
    private SyntaxToken? _namespaceKeywordToken;


    private SyntaxList<SyntaxToken>? _orderTokens;

    internal MetadataOrder(SyntaxKinds kind, SyntaxNode? parent) :
        base(kind, parent)
    {
    }

    /// <summary>
    ///     排序关键字集合
    ///     [ rot[ate] | ran[domize] | rev[erse] | asc[ending] | desc[ending] ] ]
    /// </summary>
    public IReadOnlyList<SyntaxToken> OrderTokens =>
        _orderTokens == null ? new List<SyntaxToken>() : _orderTokens;


    /// <summary>
    ///     namespace 关键字
    /// </summary>
    public SyntaxToken? NamespaceKeywordToken => _namespaceKeywordToken;


    /// <summary>
    ///     fix 关键字
    /// </summary>
    public SyntaxToken? FixKeywordToken => _fixKeywordToken;


    /// <summary>
    ///     添加一个排序关键字
    /// </summary>
    public void AddOrder(SyntaxToken token)
    {
        Debug.Assert(token.IsOneOfNode(
            SyntaxKinds.RotKeywordToken, // Rot
            SyntaxKinds.RotateKeywordToken, // Rotate
            SyntaxKinds.RanKeywordToken, // Ran
            SyntaxKinds.RandomizeKeywordToken, // Randomize
            SyntaxKinds.RevKeywordToken, // Rev
            SyntaxKinds.ReverseKeywordToken, // Reverse
            SyntaxKinds.AscKeywordToken, // Asc
            SyntaxKinds.AscendingKeywordToken, // Ascending
            SyntaxKinds.DescKeywordToken, // Desc
            SyntaxKinds.DescendingKeywordToken // Descending
        ));
        AddChildMember(ref _orderTokens, token);
    }


    public void Fix(SyntaxToken fixKeywordToken)
    {
        Debug.Assert(fixKeywordToken.IsNode(SyntaxKinds.FixKeywordToken));
        SetChildNullableField(ref _fixKeywordToken, fixKeywordToken);
    }


    public void Update(SyntaxToken namespaceKeywordToken)
    {
        Debug.Assert(namespaceKeywordToken.IsNode(SyntaxKinds.NamespaceKeywordToken));
        SetChildNullableField(ref _namespaceKeywordToken, namespaceKeywordToken);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        AcceptList(visitor, OrderTokens);
        Accept(visitor, FixKeywordToken, NamespaceKeywordToken);
    }
}